#ifndef Deque_h__
#define Deque_h__


/*
============
    Deque
        first in and last out, operation on front & back
============
*/

namespace inf {

    template< typename Type >
    class Deque {
    public:
        bool	empty( void ) const;
        int		size( void ) const;

        void	clear( void );
        void	set_granularity( int newGranularity );

        void	push_back( const Type& element );
        void	pop_back( void );
        Type&	back( void );

        Type&	front( void );
        void	push_front( const Type& element );
        void	pop_front( void );

        void	swap( Deque& rhs );
    private:
        List< Type > list;
    };

    /*
    ============
    Deque< Type >::push_back
    ============
    */
    template< typename Type >
    void Deque< Type >::push_back( const Type& element ) {
        list.append( element );
    }

    /*
    ============
    Deque< Type >::pop_back
    ============
    */
    template< typename Type >
    void Deque< Type >::pop_back( void ) {
        list.remove_index( size() - 1 );
    }

    /*
    ============
    Deque< Type >::back
    ============
    */
    template< typename Type >
    Type& Deque< Type >::back( void ) {
        return list[ size() - 1 ];
    }

    /*
    ============
    Deque< Type >::push_front
    ============
    */
    template< typename Type >
    void Deque< Type >::push_front( const Type& element ) {
        list.insert( element, 0 );
    }

    /*
    ============
    Deque< Type >::pop_front
    ============
    */
    template< typename Type >
    void Deque< Type >::pop_front( void ) {
        list.remove_index( 0 );
    }

    /*
    ============
    Deque< Type >::front
    ============
    */
    template< typename Type >
    Type& Deque< Type >::front( void ) {
        return list[ 0 ];
    }

    /*
    ============
    Deque< Type >::clear
    ============
    */
    template< typename Type >
    void Deque< Type >::clear( void ) {
        list.clear();
    }

    /*
    ============
    Deque< Type >::set_granularity
    ============
    */
    template< typename Type >
    void Deque< Type >::set_granularity( int newGranularity ) {
        list.set_granularity( newGranularity );
    }

    /*
    ============
    Deque< Type >::empty
    ============
    */
    template< typename Type >
    bool Deque< Type >::empty( void ) const {
        return list.size() == 0;
    }

    /*
    ============
    Deque< Type >::size
    ============
    */
    template< typename Type >
    int Deque< Type >::size( void ) const {
        return list.size();
    }

    /*
    ============
    Deque< Type >::swap
    ============
    */
    template< typename Type >
    void Deque< Type >::swap( Deque& rhs ) {
        list.swap( rhs.list );
    }


}   // ::inf

#endif // Deque_h__
